﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Reflection;
using System.IO;

namespace Super64.Configuration
{
    public static class Config
    {
        private static void LoadObjectData(Type type, XmlTextReader reader)
        {
            try
            {
                if (!reader.ReadToFollowing(type.Name))
                    return;
            }
            catch (System.Xml.XmlException)
            {
                return;
            }

            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);

            foreach (FieldInfo info in fields)
            {
                try
                {
                    if (!reader.ReadToFollowing(info.Name))
                        continue;

                    Type t = Type.GetType(reader.GetAttribute("type"));
                    object data = reader.ReadElementContentAs(t, null);
                    info.SetValue(type, data);
                }
                catch (FieldAccessException)
                {
                    continue;
                }
            }
        }
        private static void SaveObjectData(Type type, XmlTextWriter writer)
        {
            FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);

            writer.WriteRaw("\r\n\t");
            writer.WriteStartElement(type.Name);


            foreach (FieldInfo info in fields)
            {
                writer.WriteRaw("\r\n\t\t");
                writer.WriteStartElement(info.Name);
                writer.WriteAttributeString("type", info.FieldType.FullName);

                object data = info.GetValue(type);

                if (data != null)
                {
                    writer.WriteValue(data);
                }
                else
                {
                    writer.WriteValue("null");
                }

                writer.WriteFullEndElement();
            }

            writer.WriteRaw("\r\n\t");
            writer.WriteFullEndElement();
        }

        public static void SaveConfig()
        {
            FileStream file = new FileStream(Paths.ConfigPath, FileMode.Create, FileAccess.Write, FileShare.Read);
            XmlTextWriter writer = new XmlTextWriter(file, new UTF8Encoding());
            writer.WriteStartElement("EimuConfig");
            SaveObjectData(typeof(GeneralConfig), writer);
            writer.WriteRaw("\r\n");
            writer.WriteFullEndElement();
            writer.Close();
            file.Close();
        }

        public static void LoadConfig()
        {
            if (!File.Exists(Paths.ConfigPath))
                SaveConfig();

            FileStream file = new FileStream(Paths.ConfigPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            XmlTextReader reader = new XmlTextReader(file);

            try
            {
                // Test Read for root node
                reader.Read();
            }
            catch (XmlException)
            {
                reader.Close();
                file.Close();
                SaveConfig();
                // Retry
                LoadConfig();
            }

            LoadObjectData(typeof(GeneralConfig), reader);
            reader.Close();
            file.Close();
        }
    }
}
